<html><head>

<link rel="stylesheet" href="style_product.css" type="text/css"><title>Definition of the SRV-1 Control Protocol (Blackfin Version)</title></head><body>
<a href="http://www.surveyor.com/"><img src="http://www.surveyor.com/images/surveyor.gif" border="0"></a><br>
<h3>Definition of the SRV-1 Control Protocol (Blackfin Version) - as of 24 April
 2010</h3>

<table width="720">
<tbody><tr><td>All commands from the host to the SRV-1 robot are
comprised of ASCII characters or ASCII followed by 8-binary or ASCII decimal characters.  All commands receive an
acknowledgment from the robot to the host, which is either a '#'
character followed by the command, or '##' for variable length
responses. Variable length commands which don't specify a return size
append a CR + newline ('\r\n') to their response.</td>
</tr><tr><td></td>
</tr><tr><td>Note that all of these commands can be executed via a
terminal program with TCP / telnet capability.  For example, you can connect using the 'netcat' command via<br>
'nc robot-ip 10001'</td>
</tr><tr><td></td>
</tr><tr><td>When the robot first powers up, it will dump the 'V'
Version command results ("##Version ...\r\n") so you can see what version
of firmware is running. There is typically a 2 second delay after
startup before the robot can accept any commands while the camera and
other sensors are initialized - you should see the yellow LED's flash when the processor reboots.
After startup, just to test that there
is 2-way communication, send an 'V' to access the firmware version string.
The only command that will
produce strange results is the 'I' IMJ command, which grabs a JPEG
frame - this will flood the screen with binary characters.</td>
</tr><tr><td></td>
</tr><tr><td>The firmware has a built-in C interpreter called "picoC".  The 'Q' command will execute the C program that has been stored
in the robot's flash buffer and the '!' command will run C interactively, terminated with an ESC.  The flash buffer can be set by the 'zr' command which transfers the contents of the user flash segment to the flash buffer, or via the 'X' command which
transfers a file from the host via XMODEM protocol.  Before executing a program, the contents of the 
flash buffer can be examined using 'zd'.  When the program finishes (assuming the C program isn't running an infinite loop), control
returns to the C interpreter, unless the exit() function is called in the C program, which similar to ESC returns control to the
regular SRV-1 command processing loop.  If the autorun(x) function is placed at the beginning of a program which is stored
in flash sector #4, the robot will start running the stored C program unless ESC character is
received within 'x' seconds of startup.
</td>
</tr><tr><td></td>
</tr><tr><td>If there are any questions about this protocol, send email to <a href="mailto:support@surveyor.com">support@surveyor.com</a> or check the <a href="http://www.surveyor.com/robot_forum.html">Surveyor Robotics Forum</a>.</td>
</tr><tr><td></td>
</tr></tbody></table>
<br>
<table border="1" width="720">
<tbody><tr><th>Command</th><th>Response</th><th>Description
</th></tr><tr><th></th><th></th><th>
</th></tr><tr><th></th><th></th><th>
</th></tr><tr><th>Core Robot Commands</th><th></th><th>
</td></tr><tr><td>except for 'q' command, all parameters are sent as 8-bit binary characters (0x00 - 0xFF)</td><td></td><td>
</td></tr><tr><th></th><th></th><th>
</th></tr><tr><td>'7'</td><td>'#7'</td><td>note that keypad commands ('1' - '9') don't become active until an 'Mxxx' motor control command has been received<br><br>robot drift left
</td></tr><tr><td>'8'</td><td>'#8'</td><td>robot drive forward
</td></tr><tr><td>'9'</td><td>'#9'</td><td>robot drift right
</td></tr><tr><td>'4'</td><td>'#4'</td><td>robot drive left
</td></tr><tr><td>'5'</td><td>'#5'</td><td>robot stop
</td></tr><tr><td>'6'</td><td>'#6'</td><td>robot drive right
</td></tr><tr><td>'1'</td><td>'#1'</td><td>robot back left
</td></tr><tr><td>'2'</td><td>'#2'</td><td>robot drive back
</td></tr><tr><td>'3'</td><td>'#3'</td><td>robot back right
</td></tr><tr><td>'0'</td><td>'#0'</td><td>robot rotate left 20-deg
</td></tr><tr><td>'.'</td><td>'#.'</td><td>robot rotate right 20-deg
</td></tr><tr><th></th><th></th><th>
</td></tr><tr><td>'+'</td><td>'#+'</td><td>increase motor/servo level
</td></tr><tr><td>'-'</td><td>'#-'</td><td>decrease motor/servo level
</td></tr><tr><td>'<'</td><td>'#<'</td><td>trim motor balance toward left
</td></tr><tr><td>'>'</td><td>'#>'</td><td>trim motor balance toward right
</td></tr><tr><th></th><th></th><th>
</th></tr><tr><td>'a'</td><td>'#a'</td><td>set capture resolution to 160x120
</td></tr><tr><td>'b'</td><td>'#b'</td><td>set capture resolution to 320x240
</td></tr><tr><td>'c'</td><td>'#c'</td><td>set capture resolution to 640x480
</td></tr><tr><td>'d' or 'A'</td><td>'#A'</td><td>set capture resolution to 1280x1024
</td></tr><tr><th></th><th></th><th>
</td></tr><tr><td>'D'</td><td>'##D'</td><td>checks MN13812 battery level detect circuit on SVS<br>
returns:<br>
##D - battery voltage okay<br>
##D - low battery voltage detected<br>
</td></tr><tr><th></th><th></th><th>
</td></tr><tr><td>'E'</td><td></td><td>launches flash buffer line editor -<br>
(T)op (B)ottom (P)reviouse (N)ext line (L)ist (I)nsert until ESC (D)elete (H)elp (X)exit
</th></tr><tr><td>'Fab'</td><td>'#F'</td><td>Enables Failsafe mode for motor control<br>
'ab' parameters sent as 8-bit binary<br><br>
a = left motor/servo failsafe level, b = right motor/servo failsafe level.<br><br>
sets motor/servo levels for 'M' and 'S' commands in case no command is received via the radio link within 2 seconds.  
</th></tr><tr><td>'f'</td><td>'#f'</td><td>disables Failsafe mode
</td></tr><tr><th></th><th></th><th>
</th></tr><tr><td>'G'</td><td>HTML stream</td><td>HTTP GET command - parses HTTP request, e.g.<br>
GET /index.html HTTP/1.1 <br><br>
- recognizes files /00.html .. /09.html, stored respectively in flash sectors 10/11, 12/13 .. 28/29 <br><br>
- /index.html == /00.html<br><br>
- will replace "$$camera$$" with base64 live captured JPEG <br><br>
- use 'zBxx' to store in sector pair - zb10 stores 128kB from flash buffer to sectors 10/11<br>
</td></tr><tr><th></th><th></th><th>
</td></tr><tr><td>'I'</td><td>'##IMJxs0s1s2s3....'</td><td>grab JPEG compressed video frame
<br><br> x = frame size in pixels:<br>   1 = 80x64, 3 = 160x120, 5 = 320x240, 7 = 640x480, 9 = 1280x1024
<br><br> s0s1s2s3=frame size in bytes (s0 * 256^0 + s1 * 256^1 + s2 * 256^2 + s3 * 256^3)
<br> .... = full JPEG frame
<br><br> Note that sometimes the 'I' command returns nothing if the
robot camera is busy, so the 'I' command should be called as many times
as needed until a frame is returned
</th></tr><tr><td>'irab'</td><td>'##iraa cc'</td><td>I2C register read ('ab' parameters sent as 8-bit binary)<br>
a is device id, b is register, cc is 8-bit return value from register displayed as decimal value
</th></tr><tr><td>'iRab'</td><td>'##iRaa cc'</td><td>I2C register read ('ab' parameters sent as 8-bit binary)<br>
a is device id, b is register, cc is 16-bit return value from register displayed as decimal value
</th></tr><tr><td>'iMabc'</td><td>'##iMaa xx xx ... xx'</td><td>I2C multiple register read ('abc' parameters sent as 8-bit binary)<br>
a is device id, b is register, c is count, xx is 8-bit return values from register displayed as decimal value
</th></tr><tr><td>'iwabc'</td><td>'##iwaa'</td><td>I2C register write ('abc' parameters sent as 8-bit binary)<br>
a is device id, b is register, c is value written to register
</th></tr><tr><td>'iWabcd'</td><td>'##iWaa'</td><td>multi-byte I2C register write ('abcd' parameters sent as 8-bit binary)<br>
a is device id, b is first byte, c is second byte, d is third byte
</th></tr><tr><td>'idabcef'</td><td>'##idaa'</td><td>I2C dual register write ('abcde' parameters sent as 8-bit binary)<br>
a is device id, b is register 1, c is value written to register 1, d is register 2, e is value written to register 2
</td></tr><tr><th></th><th></th><th>
</th></tr><tr><td>'l'</td><td>'#l'</td><td>turn on lasers
</td></tr><tr><td>'L'</td><td>'#L'</td><td>turn off lasers
</td></tr><tr><th></th><th></th><th>
</th></tr><tr><td>'Mabc'</td><td>'#M'</td><td>direct motor control<br>
'abc' parameters sent as 8-bit binary<br>
<br> a=left speed, b=right speed, c=duration*10milliseconds
<br><br> speeds are 2's complement 8-bit binary values - 0x00 through 0x7F is
forward, 0xFF through 0x81 is reverse, e.g. the decimal equivalent of the 4-byte sequence 0x4D 0x32
0xCE 0x14 = 'M' 50 -50 20 (rotate right for 200ms)
<br><br> duration of 00 is infinite, e.g. the 4-byte sequence 0x4D 0x32 0x32 0x00 = M 50 50 00 (drive forward at 50% indefinitely)
</th></tr><tr><td>'mabc'</td><td>'#m'</td><td>to employ direct PWM motor control of 2nd bank of timers (TMR6 and TMR7) - same format as 'M' command<br>
</td></tr><tr><th></th><th></th><th>
</th></tr><tr><td>'o'</td><td>'#o'</td><td>enable caption overlay
</td></tr><tr><td>'O'</td><td>'#O'</td><td>disable caption overlay
</th></tr><tr><td>'p'</td><td>'##ping xxxx xxxx xxxx xxxx\r\n'</td><td>ping ultrasonic ranging modules attached to pins 27, 28, 29, 30 with trigger on pin 18 - tested with Maxbotics EZ0 and EZ1 modules.  xxxx return value is range in inches * 100 (2500 = 25 inches)
</th></tr><tr><td>'qx'</td><td>'##quality x\r\n'</td><td>sets JPEG quality between 1-8 ('x' is an ASCII decimal character).  1 is highest, 8 is lowest
</td></tr><tr><td>'R'</td><td>'##Range(cm) = xxx'</td><td>measure range to nearest obstacle using laser pointers
</td></tr><tr><td>'r'</td><td>'##Range(cm)'</td><td>same as 'R', but with lots of diagnostic output
</td></tr><tr><th></th><th></th><th>
</th></tr><tr><td>'Sab'</td><td>'#S'</td><td>direct servo control (TMR2 and TMR3) <br>
'ab' parameters sent as 8-bit binary<br><br>
a=left servo setting (0x00-0x64), b=right servo setting (0x00-0x64)
<br><br> servo settings are 8-bit binary values, representing timing pulse widths ranging from 1ms to 2ms.  0x00 corresponds to a 1ms pulse, 0x64 corresponds to a 2ms pulse, and 0x32 is midrange with a 1.5ms pulse
</td></tr><tr><th></th><th></th><th>
</th></tr><tr><td>'sab'</td><td>'#s'</td><td>direct servo control of 2nd bank of servos (TMR6 and TMR7)<br>
'ab' parameters sent as 8-bit binary<br><br>
a=left servo setting (0x00-0x64), b=right servo setting (0x00-0x64)
<br><br> servo settings are 8-bit binary values, representing timing pulse widths ranging from 1ms to 2ms.  0x00 corresponds to a 1ms pulse, 0x64 corresponds to a 2ms pulse, and 0x32 is midrange with a 1.5ms pulse
</td></tr><tr><th></th><th></th><th>
</td></tr><tr><th></th><th></th><th>
</th></tr><tr><td>'t'</td><td>'##time - millisecs: xxxx\r\n'</td><td>outputs time in milliseconds since reset
</th></tr><tr><td>'Tx'</td><td>'#T'</td><td>changes threshold in 'g2' edge detection - T4 is default, range is T1 to T9
</td></tr><tr><th></th><th></th><th>
</th></tr><tr><td>'V'</td><td>'##Version ...\r\n'</td><td>read firmware version info<br>response is terminated by newline character
</th></tr><tr><td>'X'</td><td>'#Xmodem transfer count: bytes'</td><td>Xmodem-1K file transfer - receive file via xmodem protocol - store in flash buffer
</th></tr><tr><td>'y'</td><td>'#y'</td><td>flip video capture (for use with upside-down camera)
</th></tr><tr><td>'Y'</td><td>'#Y'</td><td>restore video capture to normal orientation
</td></tr><tr><td>'zAxx'</td><td>'##zA - read 131072 bytes\r\n'</td><td>flash memory large read - read 128kb from specified flash sector pair xx 02/03 ... 62/63 to flash buffer (e.g. read C program from flash sector before running C interpreter).  Sectors 00 and 01 are off-limits.
</th></tr><tr><td>'zBxx'</td><td>'##zB - wrote 131072 bytes\r\n'</td><td>flash memory large write - write 128kb from flash buffer to specified flash sector buffer pair 02/03 ... 62/63 (sectors 00 and 01 are off-limits)
</td></tr><tr><td>'zc'</td><td>'##zclear\r\n'</td><td>clear contents of flash buffer
</td></tr><tr><td>'zC'</td><td>'##zCRC xxxx\r\n'</td><td>compute crc16_ccitt for flash buffer
</td></tr><tr><td>'zd'</td><td>'##zd...\r\n'</td><td>flash buffer dump - dump contents of flash memory buffer to console
</td></tr><tr><td>'zr'</td><td>'##zr\r\n'</td><td>flash memory read - read 65kb from user flash sector to flash buffer (e.g. read C program from flash sector before running C interpreter)
</td></tr><tr><td>'zRxx'</td><td>'##zRead\r\n'</td><td>flash memory read - read 65kb from specified flash sector xx (02 - 63) to flash buffer (e.g. read C program from flash sector before running C interpreter).  Sectors 00 and 01 are off-limits.
</th></tr><tr><td>'zw'</td><td>'##zw\r\n'</td><td>flash memory write - write 65kb from flash buffer to user flash sector
</th></tr><tr><td>'zWxx'</td><td>'##zWxx\r\n'</td><td>flash memory write - write 65kb from flash buffer to specified flash sector 02-63 (sectors 00 and 01 are off-limits)
</td></tr><tr><td>'zZ'</td><td>'##zZ\r\n'</td><td>flash memory boot sector update - writes contents of flash buffer to boot sectors of flash memory - used to replace u-boot.ldr or srv1.ldr - checks first that a valid LDR format image is in the flash buffer
</td></tr><tr><th></th><th></th><th>
</td></tr><tr><th></th><th></th><th>

</th></tr><tr><th>Special Commands</th><th></th><th>
</th></tr><tr><th></th><th></th><th>
</th></tr><tr><td>'$!'</td><td></td><td>reset Blackfin
</th></tr><tr><td>'$E'</td><td></td><td>read optional wheel encoders on GPIO-H14 and H15
</th></tr><tr><td>'$ex'</td><td></td><td>x = motor # (1-4);  read cummulative pulse count from wheel encoder on SRV-4WD
</th></tr><tr><td>'$g'</td><td></td><td>parse GPS input
</th></tr><tr><td>'$R'</td><td></td><td>SVS command - configures slave Blackfin to receive SPI transfer to flash buffer
</th></tr><tr><td>'$X'</td><td></td><td>SVS command - configures master Blackfin to transfer contents of flash buffer via SPI
</th></tr><tr><td>'$Axx'</td><td>'##$Axx yyyy\r\n'</td><td>read AD7998 A/D channel xx (01-08, 11-18 or 21-28)
</th></tr><tr><td>'$C'</td><td>'##$C xxx\r\n'</td><td>read HMC6352 compass
</th></tr><tr><td>'$c'</td><td>'##c heading=344  x=-505 y=-110 z=447  xmin=-1032 xmax=-228 ymin=-970 ymax=-89\r\n'</td><td>read HMC5843 compass
</th></tr><tr><td>'$Ta'</td><td>'##$Tx yyyy\r\n'</td><td>read LIS3LV02DQ tilt sensor channel a (1 = x axis, 2 = y axis, 3 = z axis)
</th></tr><tr><th></th><th></th><th>
</td></tr><tr><th></th><th></th><th>

</th></tr><tr><th>Vision Commands</th><th></th><th>
</th></tr><tr><th></th><th></th><th>
</td></tr><tr><td>all parameters are sent as ASCII decimal characters ('0' - '9')</td><td></td><td>
</th></tr><tr><th></th><th></th><th>
</th></tr><tr><td>'g0'</td><td>'##g0'</td><td>grab reference frame and enable frame differencing
</th></tr><tr><td>'g1'</td><td>'##g1'</td><td>enable color segmentation
</th></tr><tr><td>'g2'</td><td>'##g2'</td><td>enable edge detection (threshold changed with 'T' command)
</th></tr><tr><td>'g3'</td><td>'##g3'</td><td>enable horizon detection (threshold changed with 'T' command)
</th></tr><tr><td>'g4'</td><td>'##g4'</td><td>enable obstacle detection (threshold changed with 'T' command)
</th></tr><tr><td>'g5'</td><td>'##g5'</td><td>enable stereo processing (only works with SVS that has GPIO-H8 connection between processors)
</th></tr><tr><td>'g6x'</td><td>'##g6 bin# x'</td><td>graphically overlay blob search results for color bin# x (e.g. 'g63' displays blobs matching color bin 3)
</th></tr><tr><td>'g_'</td><td>'#g_'</td><td>disable frame differencing / color segmentation / edge detection. 
the '_' in 'g_' could be any character other than 0, 1, 2, 3, 4
</th></tr><tr><th></th><th></th><th>
<tr><td>'vax'</td><td>'##vax\r\n'</td><td>the 'va' command enables/disables automatic gain, white balance and exposure camera functions (default x=7)<br>  x=4 -> AGC enable<br> x=2 -> AWB enable<br> x=1 -> AEC enable<br>  x=7 -> AGC+AWB+AEC on<br>  x=0 -> AGC+AWB+AEC off
</td></tr><tr><td>'vbc'</td><td>'##vbc dd\r\n ssss x1 x2 y1 y2\r\n ....'</td><td>the
'vb' command searches for blobs matching the colors in color bin #c, indicates the number of blobs found as dd,
and returns a count of matching pixels
in the blob, along with coordinates of an x1, x2, y1, y2 rectangular region
containing the matching pixels. up to 16 blobs can be returned, and the blobs are sent in
order of pixel count, though blobs smaller than MIN_BLOB_SIZE
(currently set to 5 pixels) aren't shown.
</td></tr><tr><td>'vccy1y2u1u2v1v2'</td><td>'##vcc\r\n'</td><td>the 'vc' command directly sets the contents of color bin #c.  <br>
this command will return string with 'vc' followed by the color bin number.  <br>
for example, we could save a set of colors to color bin #3
corresponding to measurements taken at another time, such as the above
mentioned orange golf ball color measurement, using 'vc3127176086111154200'.
we could then confirm that the colors were properly stored by issuing
the command 'vr3' to retrieve the contents of color bin #3.
</td></tr><tr><td>'vfxxx1xxx2yyy1yyy2'</td><td>'##vf xxxx\r\n'</td><td>the 'vf' counts the number of pixels matching color bin #c in the range of x1, x2, y1, y2<br>
e.g.  'vf10100020001500220'  searches for color bin #1 pixels in the x range from 100-200 and y range from 150-220 <br>
</td></tr><tr><td>'vh'</td><td>'##vhist y  u  v\r\n'</td><td>computes and lists the distribution of Y, U and V pixels over the entire range of possible values, divided into bins of 0-3, 4-7, 8-11, ... 248-251, 252-255
</td></tr><tr><td>'vm'</td><td>'##vmean yy uu vv\r\n'</td><td>computes mean values for Y, U and V over the entire image.
</td></tr><tr><td>'vpxxxxyyyy'</td><td>'##vp yyy uuu vvv\r\n'</td><td>the 'vp' command samples a single pixel defined by coordinates xxxx (column 0000-0159, 0000-0319, 0000-0639, 0000-1279 depending on resolution) and yy (row 0000-0127, 0000-0255, 0000-0511, 0000-1023, where 0000 is top of image). 'vp01600128' will sample a pixel in the middle of the image at 320x256 resolution, 'vp01600000' will sample a pixel in the middle of the top row, etc...
</td></tr><tr><td>'vrc'</td><td>'##vrc y1 y2 u1 u2 v1 v2\r\n'</td><td>the 'vr' command retrieves the stored color info from color bin #c.  <br>this command will return string with 'vr' followed by the color bin number,
followed by y1=Ymin, y2=Ymax, u1=Umin, u2=Umax, v1=Vmin, v2=Vmax. <br>
in the above example where colors for an orange golf ball were captured
using the 'vg' command for color bin #0, issuing a 'vr0' command will
return the colors stored in color bin #0 - e.g. '##vr0 127 176 86 111 154 200\r\n'. 
</td></tr><tr><td>'vsx'</td><td>'##vscan = pix xxxx xxxx xxxx xxxx ... xxxx\r\n'</td><td>vs scans for edge pixels in x (1-9) columns using edge_thresh set by 'T' or 'vt' command.  displays total number of edge pixels found and distance from bottom to first edge pixel in each column
</td></tr><tr><td>'vtxxx'</td><td>'##vthresh xxxx\r\n'</td><td>vt sets the edge_thresh global variable from 0000-9999 for edge detection (default is 3200).  equivalent to 'T' console function but with more precision
</td></tr><tr><td>'vzx'</td><td>'##vzero\r\n'</td><td>vz0 zeros out all of the color bins, vz1 / vz2 / vz3 / vz4 segments colors into various color spaces which can be used by enabling 'g1' color segmentation function ('G' turns it off)
</th></tr><tr><th></th><th></th><th>

</th></tr><tr><th>Neural Network Commands</th><th></th><th>
</th></tr><tr><th></th><th></th><th>
</td></tr><tr><td>all parameters are sent as ASCII hex characters ('0' - 'f')</td><td></td><td>
</th></tr><tr><th></th><th></th><th>
<tr><td>'np'</td><td</td><td>store a new pattern</td></tr>
<tr><td>'nd'</td><td</td><td>display a stored pattern</td></tr>
<tr><td>'ni'</td><td</td><td>initialize the network with random weights</td></tr>
<tr><td>'nt'</td><td</td><td>train the network from stored patterns</td></tr>
<tr><td>'nx'</td><td</td><td>test the network with sample pattern</td></tr>
<tr><td>'ng'</td><td</td><td>grab a pattern using blob located by "vb"</td></tr>
<tr><td>'nb'</td><td</td><td>match pattern against specific blob from "vb"</td></tr>
</th></tr><tr><th></th><th></th><th>

</th></tr><tr><th></th><th></th><th>

</th></tr><tr><th>C interpreter</th><th></th><th>
</th></tr><tr><th></th><th></th><th>

</th></tr><tr><td>'Q'</td><td>execute C program</td><td>runs C program 
stored in flash buffer, which got there via the 'E' line editor, the 
'zr' or 'zRxx' command (which reads a flash sector into flash 
buffer) or 'X' command (XMODEM file transfer)<br><br>
</th></tr><tr><th></th><th></th><th>
</th></tr><tr><td>'!'</td><td>run C interactively</td><td>send ESC to 
exit<br>
</td></tr><tr><th>
See <a href="http://www.surveyor.com/C.html">www.surveyor.com/C.html</a> 
for full C interpreter documentation<br>
</th></tr></tbody></table>
<br><br>
last updated 24 April 2010 - 23:50 GMT
<br>
<script src="urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-226226-1";
urchinTracker();
</script>

</body></html>
